<?php
/**
 * A rail_group has some rail_user objects as members.
 *
 * PHP versions 5
 *
 * Copyright (C)
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of ERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software
 * Fundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
 *
 * @author Bastian Schröder <bs@chemanet.de>
 * @version 2008-01-25
 * @package rail
 */
class rail_group extends rail_object {

	/**
	 * Relations which are not writeable from outside. Outside means by calling set_relation or remove_relation method.
	 * The array contains only the name of protected relation not the object associated with the relation.
	 *
	 * @var array
	 */
	protected $protected_relations = array( RAIL_MEMBERSHIP );


	/**
	 * Add a rail_user to this group.
	 *
	 * @exception rail_writepermission_exception
	 * @param rail_user $pRailUser
	 */
	public function add_member ( $pRailUser ) {
		// check write permission
		if( !$this->is_writeable() )
		 	throw new rail_writepermission_exception( $this, $this->rail_connector->get_user() );

		// only add if membership dosn't exist.
		if( !$this->is_member( $pRailUser ) )
			$this->set_relation( $pRailUser, RAIL_MEMBERSHIP );
	}


	/**
	 * Count all rail_user objects who are members of this rail_group.
	 *
	 * @exception rail_readpermission_exception
	 * @return int
	 */
	public function count_members () {
		// check read permission
		if( !$this->is_readable() )
		 	throw new rail_readpermission_exception( $this, $this->rail_connector->get_user() );

		$size = 0;

		// get all RAIL_MEMBERSHIP
		$data = $this->rail_connector->send_request( "SELECT id FROM objects_relations WHERE `type`='RAIL_MEMBERSHIP' AND (`object1`='" . $this->get_id() . "' OR `object2`='" . $this->get_id() . "')" );
		while( $data_row = $data->fetch_assoc() )
			$size ++ ;

		// get all objetes has this as group
		$data = $this->rail_connector->send_request("SELECT `id` FROM objects WHERE `type`='rail_user' AND `group`='" . $this->get_id() . "'");
		while( $data_row = $data->fetch_assoc() )
			$size ++ ;

		return $size;
	}


	/**
	 * Delete this rail_group. Change the primary group to root for all rail_object has this group as primary group.
	 * You are not able to delete root users group.
	 *
	 * @exception rail_writepermission_exception
	 */
	public function delete () {
		// check write permission
		if( !$this->is_writeable() )
		 	throw new rail_writepermission_exception( $this, $this->rail_connector->get_user() );

		// get root users group rail_id
		$data = $this->rail_connector->send_request( "SELECT objects.`group` FROM objects, objects_attributes WHERE objects.`id`=objects_attributes.`object` AND objects.`type`='RAIL_USER' AND objects_attributes.`attribute`='OBJ_NAME' AND objects_attributes.`value`='root' LIMIT 1" )->fetch_assoc();
		$rail_id = $data['group'];

		// check wheater trying to delete roots group
		if( $rail_id == $this->get_group() )
			throw new rail_writepermission_exception( $this, $this->rail_connector->get_user(), 'Can\'t delete root users group.' );

		// change group for all rail_objects owned by deleted group to root
		$this->rail_connector->send_request( "UPDATE objects SET `group`='$rail_id' WHERE `group`='" . $this->get_id() . "' AND `id`<>'" . $this->get_id() . "'" );

		return parent::delete();
	}


	/**
	 * Return true if rail_user is a member from this rail_group.
	 *
	 * @exception rail_readpermission_exception
	 * @param rail_user $pRailUser
	 * @return bool
	 */
	public function is_member ( $pRailUser ) {
		// check read permission
		 if( !$this->is_readable() )
		 	throw new rail_readpermission_exception( $this, $this->rail_connector->get_user() );
		// check read permission on rail_user
		 if( !$pRailUser->is_readable() )
		 	throw new rail_readpermission_exception( $pRailUser, $this->rail_connector->get_user() );

		 // return true if this group is the primary group for rail_user
		 if( $pRailUser->get_group()->get_id() == $this->get_id() )
		 	return true;

		// return true if rail_user has a RAIL_MEMBERSHIP relation
		$data = $this->rail_connector->send_request( "
			SELECT
				`object1`,`object2`
			FROM
				objects_relations
			WHERE
				`type`='RAIL_MEMBERSHIP'
				AND ( `object1`='" . $this->get_id() . "' OR `object2`='" . $this->get_id() . "' )
				AND (`object1`='" . $pRailUser->get_id() . "' OR `object2`='" . $pRailUser->get_id() . "' )
			LIMIT
				1
		" )->fetch_assoc();
		if( count( $data ) > 0 )
			return true;

		// otherwise return false
		return false;
	}


	/**
	 * Get all members from this rail_group. Returned array of rail_users.
	 *
	 * @exception rail_readpermission_exception
	 * @return array
	 */
	public function get_members () {
		// check read permission
		 if( !$this->is_readable() )
		 	throw new rail_readpermission_exception( $this, $this->rail_connector->get_user() );

		$objects = $this->get_relations( RAIL_MEMBERSHIP );

		// get all objetes has this as group
		$data = $this->rail_connector->send_request("SELECT `id` FROM objects WHERE `type`='rail_user' AND `group`='" . $this->get_id() . "'");
		while( $data_row = $data->fetch_assoc() ){
			foreach( $objects as $object ){
				if( $object->get_id() == $data_row[ 'id' ] )
					continue;
			}

			$objects[] = rail_factory::get_object( $this->rail_connector, $data_row[ 'id' ] );
		}

		// return
		return $objects;
	}


	/**
	 * Remove a member from this rail_group.
	 *
	 * @param rail_user $pRailUser
	 */
	public function remove_member ( $pRailUser ) {
		$this->remove_relation( $pRailUser, RAIL_MEMBERSHIP );
	}

} // End of rail_group
?>